﻿
using System.Collections.Generic;

namespace IronLua.Ast {

	public abstract class BaseAstVisitor : ILuaAstVisitor {

		public virtual void VisitList<TElement> (IEnumerable<TElement> list) where TElement : LuaNode
		{
			foreach (var e in list)
				e.Accept (this);
		}

		public virtual void VisitBlockStatement (BlockStatement node)
		{
			VisitList (node.Statements);
		}

		public virtual void VisitDoStatement (DoStatement node)
		{
			node.Body.Accept (this);
		}

		public virtual void VisitWhileStatement (WhileStatement node)
		{
			node.Condition.Accept (this);
			node.Body.Accept (this);
		}

		public virtual void VisitRepeatStatement (RepeatStatement node)
		{
			node.Body.Accept (this);
			node.Until.Accept (this);
		}

		public virtual void VisitIfStatement (IfStatement node)
		{
			node.Condition.Accept (this);
			node.Then.Accept (this);

			if (node.Else != null)
				node.Else.Accept (this);
		}

		public virtual void VisitExpressionStatement (ExpressionStatement node)
		{
			node.Expression.Accept (this);
		}

		public virtual void VisitReturnStatement (ReturnStatement node)
		{
			VisitList (node.Expressions);
		}

		public virtual void VisitBreakStatement (BreakStatement node)
		{
		}

		public virtual void VisitCommentStatement (CommentStatement node)
		{
		}

		public virtual void VisitAssignStatement (AssignStatement node)
		{
			VisitList (node.Left);
			VisitList (node.Right);
		}

		public virtual void VisitForStatement (ForStatement node)
		{
			node.Variable.Accept (this);
			node.Initializer.Accept (this);
			if (node.Step != null) node.Step.Accept (this);
			node.Body.Accept (this);
		}

		public virtual void VisitForEachStatement (ForEachStatement node)
		{
			VisitList (node.Variables);
			VisitList (node.Expressions);
			node.Body.Accept (this);
		}

		public virtual void VisitFunctionStatement (FunctionStatement node)
		{
			node.Target.Accept (this);
			node.Function.Accept (this);
		}

		public virtual void VisitMethodStatement (MethodStatement node)
		{
			node.Target.Accept (this);
			node.Function.Accept (this);
		}

		public virtual void VisitLocalStatement (LocalStatement node)
		{
			VisitList (node.Variables);
			VisitList (node.Expressions);
		}

		public virtual void VisitLocalFunctionStatement (LocalFunctionStatement node)
		{
		}

		public virtual void VisitUnaryExpression (UnaryExpression node)
		{
			node.Expression.Accept (this);
		}

		public virtual void VisitBinaryExpression (BinaryExpression node)
		{
			node.Left.Accept (this);
			node.Right.Accept (this);
		}

		public virtual void VisitLiteralExpression (LiteralExpression node)
		{
		}

		public virtual void VisitTableCreationExpression (TableCreationExpression node)
		{
		}

		public virtual void VisitVariableExpression (VariableExpression node)
		{
		}

		public virtual void VisitFunctionExpression (FunctionExpression node)
		{
			VisitList (node.Parameters);
			node.Body.Accept (this);
		}

		public virtual void VisitSlotExpression (SlotExpression node)
		{
			node.Target.Accept (this);
			node.Expression.Accept (this);
		}

		public virtual void VisitFunctionCallExpression (FunctionCallExpression node)
		{
			node.Target.Accept (this);
			VisitList (node.Arguments);
		}

		public virtual void VisitMethodCallExpression (MethodCallExpression node)
		{
			node.Target.Accept (this);
			VisitList (node.Arguments);
		}

		public virtual void VisitMemberExpression (MemberExpression node)
		{
			node.Target.Accept (this);
		}

		public virtual void VisitVarArgExpression (VarArgExpression node)
		{
		}

		public virtual void VisitElseIfClause (ElseIfClause node)
		{
		}
	}
}
